import { ComponentFactoryResolver, Injector } from '@angular/core';
import { MessagerService } from '@farris/ui-messager';
import { BsModalService } from '@farris/ui-modal';
import { NotifyService } from '@farris/ui-notify';
import { ControlContextMenuItem } from '../../../../../entity/control-context-menu';
import { EventEditorService, DomService, RefreshFormService } from '@farris/designer-services';
import { DgControl } from '../../../../../utils/dg-control';
import { QuerySchemeBuilderService } from '../../../../filter/queryScheme/context-menu/query-scheme-builder';
import { QuerySchemeFieldsEditorComponent } from '../../../../filter/queryScheme/property/editor/query-scheme-fields-editor/query-scheme-fields-editor.component';
import { QuerySchemePresetFieldsEditorComponent } from '../../../../filter/queryScheme/property/editor/query-scheme-preset-fields-editor/query-scheme-preset-fields-editor.component';
import { FarrisDesignBaseComponent } from '@farris/designer-element';

/**
 * 列表启用/移除筛选方案相关服务
 */
export class DataGridQuerySchemeContextMenuService {

    private domService: DomService;
    private messagerService: MessagerService;
    public refreshFormService: RefreshFormService;
    private notifyService: NotifyService;
    private modalService: BsModalService;
    private eventEditorService: EventEditorService;
    private resolver: ComponentFactoryResolver;

    // 筛选方案相关配置
    querySchemeConfig: any;

    constructor(private injector: Injector) {
        this.eventEditorService = this.injector.get(EventEditorService);
        this.domService = this.injector.get(DomService);
        this.notifyService = this.injector.get(NotifyService);
        this.refreshFormService = this.injector.get(RefreshFormService);
        this.messagerService = this.injector.get(MessagerService);
        this.modalService = this.injector.get(BsModalService);
        this.resolver = this.injector.get(ComponentFactoryResolver);
    }


    /**
     * 组装筛选方案菜单
     */
    assembleQuerySchemeMenu(gridComponentId: string, menuConfig: ControlContextMenuItem[]) {
        const querySchemeMenu = menuConfig.find(menu => menu.id === DgControl.QueryScheme.type);
        if (!querySchemeMenu) {
            return menuConfig;
        }
        // 若不能启用筛选方案，则移除菜单
        if (!this.checkCanEnableQueryScheme(gridComponentId)) {
            menuConfig = menuConfig.filter(menu => menu.id !== DgControl.QueryScheme.type);
            return menuConfig;
        }

        if (this.checkControlExistByType(DgControl.QueryScheme.type)) {
            querySchemeMenu.title = '移除' + querySchemeMenu.title;
            querySchemeMenu.id = 'remove' + querySchemeMenu.id;

        } else {
            querySchemeMenu.title = '启用' + querySchemeMenu.title;
            querySchemeMenu.id = 'enable' + querySchemeMenu.id;
        }

        return menuConfig;
    }

    /**
     * 校验是否允许启用筛选方案
     */
    checkCanEnableQueryScheme(gridComponentId: string) {
        // 根据模板schema中是否包含筛选方案配置来判断
        const templateOutlineSchema = this.domService.templateOutlineSchema || [];
        this.querySchemeConfig = templateOutlineSchema.find(schema => schema.queryScheme && schema.queryScheme.canEnable);
        if (!this.querySchemeConfig) {
            return false;
        }

        // 子表不支持启用筛选方案
        const gridCmp = this.domService.getComponentById(gridComponentId);
        const gridVM = this.domService.getViewModelById(gridCmp.viewModel);
        if (gridVM && gridVM.bindTo !== '/') {
            return false;
        }

        // 校验是否已启用筛选条，筛选方案和筛选条互斥，不能同时启用
        let listFilterExisted = false;
        if (this.checkControlExistByType(DgControl.ListFilter.type, gridComponentId)) {
            listFilterExisted = true;
        }


        return !listFilterExisted;
    }

    /**
     * 弹出筛选方案字段配置编辑器
     */
    openQuerySchemeModal(viewModelId: string) {
        const compFactory = this.resolver.resolveComponentFactory(QuerySchemeFieldsEditorComponent);
        const compRef = compFactory.create(this.injector);

        const modalConfig = {
            title: '筛选方案字段编辑器',
            width: 950,
            height: 500,
            showButtons: true,
            showMaxButton: true,
            buttons: compRef.instance.modalFooter
        };

        compRef.instance.value = [];
        compRef.instance.editorParams = {
            viewModelId: 'root-viewmodel',
            presetFieldConfigs: []
        };
        compRef.instance.showPropertyPanel = false;
        const modalPanel = this.modalService.show(compRef, modalConfig);
        compRef.instance.closeModal.subscribe(() => {
            modalPanel.close();
        });
        compRef.instance.submitModal.subscribe((data) => {
            if (data && data.value) {
                this.openQuerySchemePresetModal(data.value);
            }
            modalPanel.close();
        });

    }
    /**
     * 弹出筛选方案预置字段配置编辑器
     */
    private openQuerySchemePresetModal(fieldConfigs: any[]) {
        const compFactory = this.resolver.resolveComponentFactory(QuerySchemePresetFieldsEditorComponent);
        const compRef = compFactory.create(this.injector);

        const modalConfig = {
            title: '筛选方案预置字段编辑器',
            width: 950,
            height: 500,
            showButtons: true,
            showMaxButton: true,
            buttons: compRef.instance.modalFooter
        };

        compRef.instance.value = [];
        compRef.instance.editorParams = {
            fieldConfigs
        };
        const modalPanel = this.modalService.show(compRef, modalConfig);
        compRef.instance.closeModal.subscribe(() => {
            modalPanel.close();
        });
        compRef.instance.submitModal.subscribe((data) => {
            if (data && data.value) {
                const builderService = new QuerySchemeBuilderService(this.injector);
                builderService.createQuerySchemeInDocument(fieldConfigs, data.value);

                this.notifyService.success('启用成功');
                this.refreshFormService.refreshFormDesigner.next();
            }
            modalPanel.close();
        });

    }


    /**
     * 在指定组件内根据类型校验控件是否存在
     * @param controlType 控件类型
     * @param componentId 组件ID
     */
    private checkControlExistByType(controlType: string, componentId = 'root-component') {
        const rootCmp = this.domService.getComponentById(componentId);
        return this.domService.selectNode(rootCmp, item => item.type === controlType);
    }


    /**
     * 移除筛选方案
     */
    removeQueryScheme(cmpInstance: FarrisDesignBaseComponent) {
        this.messagerService.question('确定移除筛选方案？', () => {
            const builderService = new QuerySchemeBuilderService(this.injector);
            builderService.removeQuerySchemeInDocument();

            cmpInstance.emit('clearPropertyPanel');

            this.notifyService.success('已移除筛选方案');
            this.refreshFormService.refreshFormDesigner.next();
        });

    }

}
